﻿using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;

using RRRSRoguelike.Entities;
using RRRSRoguelike.Entities.Creatures;
using RRRSRoguelike.Entities.Props;
using RRRSRoguelike.Enums;
using RRRSRoguelike.Managers;

namespace RRRSRoguelike.Helpers.Actions
{
	/// <summary>
	/// Holds the methods for common generic actions
	/// </summary>
	public static class ActionHelper
	{
		/// <summary>
		/// For picking up items.
		/// </summary>
		/// <param name="position"></param>
		public static void Get(Point position)
		{

			if (GameManager.Instance.PropManager.Props.OfType<Weapon>().Any(p => p.Position == position))
			{
				if (GameManager.Instance.CreatureManager.Player.WeaponSlot != null)
					Put(position);

				var weapon = GameManager.Instance.PropManager.GetBestWeapon(position);
				GameManager.Instance.CreatureManager.Player.AddWeapon(weapon);
				GameManager.Instance.PropManager.Remove(weapon);
			}
		}

		/// <summary>
		/// For placing objects
		/// </summary>
		/// <param name="point"></param>
		public static void Put(Point point)
		{
			if (GameManager.Instance.CreatureManager.Player.WeaponSlot != null)
			{
				var weapon = GameManager.Instance.CreatureManager.Player.WeaponSlot;
				weapon.Position = GameManager.Instance.CreatureManager.Player.Position;
				GameManager.Instance.CreatureManager.Player.RemoveWeapon();
				GameManager.Instance.PropManager.Add(weapon);
			}
		}

		/// <summary>
		/// For removing buildings.
		/// </summary>
		/// <returns></returns>
		public static bool Remove()
		{
			//shortens calls.
			var ActionManager = GameManager.Instance.ActionManager;
			var player = GameManager.Instance.CreatureManager.Player;

			var built = false;
			var build = true;

			while (build)
			{
				var direction = GameManager.Instance.GameScreen.GetDirectionFromUser();

				var newPosition = DungeonLevel.GetNewPosition(player.Position, direction, 1);

				var tile = (Tile)GameManager.Instance.DungeonLevel.GetTile(newPosition, Layers.Prop);

				if (tile != null)
				{
					GameManager.Instance.PropManager.Remove(tile);
					built = true;
					build = false;
					GameManager.Instance.ForceRedraw();
				}

				else if (ActionManager.IsActionPushed(Enums.Actions.Quit) ||
						 ActionManager.IsActionPushed(Enums.Actions.Build))
				{
					build = false;
				}
			}
			return built;
		}

		/// <summary>
		/// Action for building.
		/// </summary>
		/// <param name="tile"></param>
		/// <returns></returns>
		public static bool Build(Tile tile)
		{
			//shortens calls.
			var ActionManager = GameManager.Instance.ActionManager;
			var player = GameManager.Instance.CreatureManager.Player;

			var built = false;
			var build = true;

			while (build)
			{
				var direction = GameManager.Instance.GameScreen.GetDirectionFromUser();

				var newPosition = DungeonLevel.GetNewPosition(player.Position, direction, 1);

				if (GameManager.Instance.DungeonLevel.IsOKToPlaceMonster(newPosition))
				{
					tile.Position = newPosition;
					GameManager.Instance.PropManager.Add(tile);
					GameManager.Instance.ForceRedraw();
					built = true;
					build = false;
					player.UseWeapon();
				}
				else if (ActionManager.IsActionPushed(Enums.Actions.Quit) ||
					 ActionManager.IsActionPushed(Enums.Actions.Build))
				{
					build = false;
				}
			}
			return built;
		}
				
		/// <summary>
		/// Action for shooting fireballs.
		/// </summary>
		/// <param name="position"></param>
		/// <param name="direction"></param>
		public static void ShootFireball(Point position,Direction direction)
		{
			GameManager.Instance.PropManager.Fireball = new Fireball(position, direction);
			GameManager.Instance.PropManager.Fireball.Reset();
			// should be elsewhere --> this.Flags["hasFired"] = true;
		}
		
		/// <summary>
		/// Action for fighting
		/// </summary>
		/// <param name="player"></param>
		/// <param name="monsters"></param>
		public static void Fight(Player player, List<Monster> monsters)
		{
			//get the monster on same square as player with the most hits
			var monster = monsters.OrderBy(m => m.Hits).FirstOrDefault();

			// if the player has a sword kill monster or...

			if (player.HasWeapon())
			{
				//use sword - has limited uses
				player.WeaponSlot.Use(player);

				//Kill monster
				player.KillCreature(monster);
				
				//HACK: This should now auto pick on broken sword
				if (player.WeaponSlot == null)
					Get(player.Position);

			}
			else
			{
				//Kill player
				monster.KillCreature(player);
			}
		}
	}
}
